package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.help.FormDataListSearchHelp;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.contractproduct.pojo.dto.ContractProductDeleteBatchDTO;
import com.xbongbong.pro.contractproduct.pojo.dto.ContractProductListDTO;
import com.xbongbong.pro.contractproduct.pojo.vo.ContractProductDeleteBatchVO;
import com.xbongbong.pro.contractproduct.pojo.vo.ContractProductListVO;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.WaitOutstockEnum;
import com.xbongbong.saas.enums.product.ContractProductEnum;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.service.ContractProductService;
import com.xbongbong.saas.service.ProductSerialService;
import com.xbongbong.sys.domain.entity.UserConfigEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserConfigModel;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @version v1.0
 * @date 2019/2/27 21:30
 * @since v1.0
 */
@Service("contractProductService")
public class ContractProductServiceImpl implements ContractProductService {

    private static final Logger LOG = LoggerFactory.getLogger(ContractProductServiceImpl.class);

    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private ProductSerialService productSerialService;
    @Resource
    private UserModel userModel;
    @Resource
    private UserConfigModel userConfigModel;
    @Resource
    private FormDataListSearchHelp formDataListSearchHelp;

    @Override
    public List<ContractProductEntity> findWaitOutProductEntitys(Map<String, Object> param) throws XbbException {
        return contractProductModel.findWaitOutProductEntitys(param);
    }

    @Override
    public ContractProductListVO findContractProductList(ContractProductListDTO contractProductListDTO) throws XbbException {
        ContractProductListVO contractProductListVO = new ContractProductListVO();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(contractProductListDTO, true);
            if (Objects.isNull(contractProductListDTO.getProductIdList()) && Objects.isNull(contractProductListDTO.getContractIdIn())) {
                contractProductListVO.setContractProductList(new ArrayList<>());
                return contractProductListVO;
            }
            param.put("productIdIn", contractProductListDTO.getProductIdList());
            List<ContractProductEntity> contractProductList = contractProductModel.findEntitys(param);
            if(Objects.isNull(contractProductList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            contractProductListVO.setContractProductList(contractProductList);
        } catch (Exception e) {
            LOG.error("ContractProductServiceImpl.findContractProduct 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return contractProductListVO;
    }

    @Override
    public ContractProductDeleteBatchVO deleteBatch(ContractProductDeleteBatchDTO contractProductDeleteBatchDTO) throws XbbException {
        ContractProductDeleteBatchVO contractProductDeleteBatchVO = new ContractProductDeleteBatchVO();
        try {
            List<Long> contractIdIn = contractProductDeleteBatchDTO.getContractIdIn();
            String corpid = contractProductDeleteBatchDTO.getCorpid();
            productSerialService.deleteSerial(corpid, contractIdIn, XbbRefTypeEnum.REFUND.getCode());
            contractProductModel.deleteContractAllProduct(contractIdIn, corpid, contractProductDeleteBatchDTO.getDel());
        } catch (Exception e) {
            LOG.error("ContractProductServiceImpl.deleteBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return contractProductDeleteBatchVO;
    }

    @Override
    public void dataConsistencyUpdate(String corpid, Long productId, String productName, String specification, String productNo) throws XbbException {
        try {
            contractProductModel.updateProductInfoByParentId(corpid, productId, productName, productNo, specification);

        } catch (Exception e) {
            LOG.error("ContractProductServiceImpl.dataConsistencyUpdate 出错，corpid=" + corpid + "  productId=" + productId + "  productName=" + productName + "  specification=" + specification, e);
        }
    }

    @Override
    public void updateRollbackByContractId(List<Long> contractIdIn, String corpid) throws XbbException {
        if (Objects.isNull(contractIdIn) || contractIdIn.isEmpty()) {
            return;
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put("contractIdIn", contractIdIn);
        List<ContractProductEntity> contractProductList = contractProductModel.findEntitys(param);
        if (Objects.nonNull(contractProductList) && !contractProductList.isEmpty()) {
            contractProductModel.reductionEsInUpdate(contractProductList);
        }
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return contractProductModel.getEntitysCount(param);
    }

    @Override
    public List<ContractProductEntity> getWaitOutstockProductByProductIdIn(List<Long> productIdList, String corpid) {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put("productIdIn", productIdList);
        return contractProductModel.getWaitOutstockProductByProductIdIn(param);
    }

    @Override
    public List<ContractProductEntity> findWaitPurchaseProductEntitys(FormDataListDTO formDataListDTO) throws XbbException {
        Map<String, Object> param = getWaitPurchaseParam(formDataListDTO);
        return contractProductModel.findWaitPurchaseProductEntitys(param);
    }
    @Override
    public Integer findWaitPurchaseProductCount(FormDataListDTO formDataListDTO) throws XbbException {
        Map<String, Object> param = getWaitPurchaseParam(formDataListDTO);
        return contractProductModel.findWaitPurchaseProductCount(param);
    }

    @Override
    public Integer findWaitOutStockProductCount(Map<String, Object> param) throws XbbException {
        return contractProductModel.findWaitOutStockProductCount(param);
    }

    public Map<String, Object> getWaitPurchaseParam(FormDataListDTO formDataListDTO) throws XbbException {
        UserEntity userEntity = new UserEntity();
        UserVO userVO = formDataListDTO.getLoginUser();
        BeanUtil.copyProperties(userVO, userEntity);
//        Integer dataPermission = userModel.getDataPermission(userEntity);
//        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, userVO.getUserId(), userVO.getCorpid(), BasicConstant.ZERO,false);
        String nameLike = formDataListDTO.getNameLike();
        Map<String, String> sortMap = formDataListDTO.getSortMap();
        List<ConditionsEntityExt> conditions = formDataListDTO.getConditions();
        List<Object> contractIdIn = new ArrayList<>();
        List<Object> productIdIn = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(conditions)){
            for (ConditionsEntityExt condition : conditions) {
                String attr = condition.getAttr();
                if (Objects.equals(attr,"array_2")){
                    contractIdIn.addAll((condition.getValue()));
                }else if (Objects.equals(attr,"array_1")){
                    productIdIn.addAll(condition.getValue());
                }
            }
        }
        if (CollectionUtils.isNotEmpty(formDataListDTO.getIdIn())){
            contractIdIn.addAll(formDataListDTO.getIdIn());
        }


        UserVO loginUser = formDataListDTO.getLoginUser();
        boolean isBoss = loginUser.isAdminOrBoss();

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("status", 0);
        param.put("corpid", formDataListDTO.getCorpid());
        param.put("start",(formDataListDTO.getPage()-1) * formDataListDTO.getPageSize());
        param.put("pageNum",formDataListDTO.getPageSize());
        param.put("orderByStr","update_time desc");
        param.put("type",XbbRefTypeEnum.CONTRACT.getCode());
        param.put("addTime",BasicConstant.JXC_ONLINE_DATE);
        // 默认排序
        Map<String, Object> params = BeanUtil.convertBean2Map(formDataListDTO, true);
        List<String> configAliasList = new ArrayList<>();
        configAliasList.add("waitPurchaseProductSortField");
        params.put("configAliasIn", configAliasList);
        params.put("userId", formDataListDTO.getUserId());
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        List<UserConfigEntity> userConfigList = userConfigModel.list(params);
        if (CollectionUtils.isNotEmpty(userConfigList)){
            String configValue = userConfigList.get(0).getConfigValue();
            JSONObject jsonObject = JSONObject.parseObject(configValue);
            String sortType = jsonObject.getString("sortType");
            String sortAttr = jsonObject.getString("sortAttr");
            if (StringUtil.isNotEmpty(sortAttr) && StringUtil.isNotEmpty(sortAttr)){
                if (Objects.equals(sortAttr, ContractProductEnum.NUM.getAttr())){
                    param.put("orderByStr","product_num" + " " + sortType);
                }else if (Objects.equals(sortAttr,ContractProductEnum.OUTSTOCK_NUM.getAttr())){
                    param.put("orderByStr","outstock_num" + " " + sortType);
                }else if (Objects.equals(sortAttr,ContractProductEnum.UNIT.getAttr())){
                    param.put("orderByStr","business_unit" + " " + sortType);
                }else if (Objects.equals(sortAttr,"productSerialNo")){
                    param.put("orderByStr","product_no" + " " + sortType);
                }else if (Objects.equals(sortAttr,"productName")){
                    param.put("orderByStr","product_name" + " " + sortType);
                }else if (Objects.equals(sortAttr,"addTime")){
                    param.put("orderByStr","add_time" + " " + sortType);
                }else if (Objects.equals(sortAttr,"updateTime")){
                    param.put("orderByStr","update_time" + " " + sortType);
                }
            }
        }
        //列表页排序
        if (!sortMap.isEmpty()){
            String field = sortMap.get("field");
            String sort = sortMap.get("sort");
            if (Objects.nonNull(field) && Objects.nonNull(sort)){
                if (Objects.equals(field, ContractProductEnum.NUM.getAttr())){
                    param.put("orderByStr","product_num" + " " + sort);
                }else if (Objects.equals(field,ContractProductEnum.OUTSTOCK_NUM.getAttr())){
                    param.put("orderByStr","outstock_num" + " " + sort);
                }else if (Objects.equals(field,ContractProductEnum.UNIT.getAttr())){
                    param.put("orderByStr","business_unit" + " " + sort);
                }else if (Objects.equals(field,"productSerialNo")){
                    param.put("orderByStr","product_no" + " " + sort);
                }else if (Objects.equals(field,"productName")){
                    param.put("orderByStr","product_name" + " " + sort);
                } if (Objects.equals(field,"addTime")){
                    param.put("orderByStr","add_time" + " " + sort);
                }else if (Objects.equals(field,"updateTime")){
                    param.put("orderByStr","update_time" + " " + sort);
                }
            }
        }
        if (!StringUtils.isEmpty(nameLike)){
            param.put("nameLike",nameLike);
        }
//        if (!isBoss && CollectionUtils.isNotEmpty(userIdIn)){
//            param.put("isBoss",0);
//            param.put("userIdIn",userIdIn);
//        }
        if (CollectionUtils.isNotEmpty(contractIdIn)){
            param.put("contractIdIn",contractIdIn);
        }
        if (CollectionUtils.isNotEmpty(productIdIn)){
            param.put("productIdIn",productIdIn);
        }
        return param;
    }

    /**
     * 拼接待出库列表参数
     *
     * @param formDataListDTO
     * @return
     * @throws XbbException
     */
    @Override
    public Map<String, Object> getWaitOutStockParam(FormDataListDTO formDataListDTO, List<Long> contractIds) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("corpid", formDataListDTO.getCorpid());
        param.put("start", (formDataListDTO.getPage() - 1) * formDataListDTO.getPageSize());
        param.put("pageNum", formDataListDTO.getPageSize());
        //获得排序条件
        formDataListSearchHelp.setListColumn(formDataListDTO);
        if (formDataListDTO.getSortMap().size() != 0) {
            Map<String, String> sortMap = formDataListDTO.getSortMap();
            if (WaitOutstockEnum.isProductSort(sortMap.get("field"))) {
                String value = WaitOutstockEnum.getFeildName(sortMap.get("field"));
                String desc = "desc";
                if (Objects.nonNull(sortMap.get("sort"))) {
                    desc = sortMap.get("sort");
                }
                param.put("orderByStr", value + " " + desc);
                formDataListDTO.getSortMap().clear();
            } else if (Objects.equals(sortMap.get("field"), "updateTime")) {
                param.put("orderByStr", "update_time " + sortMap.get("sort"));
                formDataListDTO.getSortMap().clear();
            } else if (Objects.equals(sortMap.get("field"), "addTime")) {
                param.put("orderByStr", "add_time " + sortMap.get("sort"));
                formDataListDTO.getSortMap().clear();
            }
        } else {
            param.put("orderByStr", "update_time desc");
        }
        if (Objects.nonNull(formDataListDTO.getNameLike())) {
            param.put("nameLike", formDataListDTO.getNameLike());
            formDataListDTO.setNameLike(null);
        }
        if (contractIds != null && !contractIds.isEmpty()) {
            param.put("contractIdIn", contractIds);
        }
        if (CollectionsUtil.isNotEmpty(formDataListDTO.getConditions())) {
            Iterator<ConditionsEntityExt> iterator = formDataListDTO.getConditions().iterator();
            while (iterator.hasNext()) {
                ConditionsEntityExt next = iterator.next();
                String attr = next.getAttr();
                List<Object> value = next.getValue();
                if (Objects.equals(attr, "array_4")) {
                    if (CollectionsUtil.isNotEmpty(value)) {
                        param.put("productIdIn", value);
                        break;
                    }
                }
            }
        }
       /* //获取用户权限
        UserEntity userEntity = new UserEntity();
        UserVO userVO = formDataListDTO.getLoginUser();
        BeanUtil.copyProperties(userVO, userEntity);
        Integer dataPermission = userModel.getDataPermission(userEntity);
        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, userVO.getUserId(), userVO.getCorpid(), BasicConstant.ONE, false);
        param.put("userIdIn", userIdIn);*/
        return param;
    }

}
